package code.whmmm.util.hikari.jdbcpool;

import com.zaxxer.hikari.pool.HikariPool;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p><b>
 * 含有事务的 工具类 <br/>
 * 未实现.....
 * </b></p>
 * <br/>
 * <pre>{@code
 * // 调用示例 .
 *
 * // 逻辑 开始
 * db.start();
 *
 * // 具体逻辑
 * db.executeUpdate("xxxxxxxx");
 *
 * // 逻辑结束
 * db.end();
 *
 * }</pre>
 * 创建时间: 2019/10/6 15:05
 *
 * @author Zero
 */
public class TxDbUtil extends AbstractDbUtil {

    private static final ThreadLocal<Connection> threadConn = new ThreadLocal<Connection>();

    private static final ThreadLocal<AtomicInteger> errorCount = new ThreadLocal<AtomicInteger>();


    public void start() {

        Connection conn = null;
        try {
            conn = pool.getConnection();
            conn.setAutoCommit(false);
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
        }
        errorCount.set(new AtomicInteger(0));

        threadConn.set(conn);


    }

    /**
     * 结束事务调用
     */
    public void end() {
        int i = errorCount.get().get();
        Connection cn = threadConn.get();
        try {
            if (i > 0) {
                cn.rollback();
            } else {
                cn.commit();
            }

            remoteValue();

            pool.evictConnection(cn);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

    }

    /**
     * 移除当前线程缓存.
     */
    private void remoteValue() {
        // 移除资源
        threadConn.remove();
        errorCount.remove();
    }

    public TxDbUtil(HikariPool p) {
        super(p);
    }

    public TxDbUtil(JdbcPoolConfig config) {
        super(config);
    }

    @Override
    public Connection getConn() {
        return threadConn.get();
    }

    @Override
    public void afterSql(ResultSet rs, Statement ps, Connection cn) {
        close(rs, ps, null);
    }

    @Override
    public void exceptionCallback(Exception e) {
        if (e != null) {
            errorCount.get().incrementAndGet();
            end();
        }
    }

    @Override
    public void commit(Connection cn) {

    }

    @Override
    public void rollback(Connection cn) {

    }


}
